home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- * CagdCmpt.c - Make objects compatible. *
- *******************************************************************************
- * Written by Gershon Elber, Sep. 91. *
- ******************************************************************************/
-
- #include "cagd_loc.h"
-
- /******************************************************************************
- * Given two curves, make the compatible by: *
- * 1. Coercing their point type to be the same. *
- * 2. Make them have the same curve type. *
- * 3. Raising the degree of the lower one to be the same. *
- * 4. Refine them to a common knot vector (If Bspline). *
- * Note 3 is preformed if SameOrder TRUE, 4 if SameKV TRUE. *
- * Returns TRUE if succesfull. Both Curves are modified IN PLACE. *
- ******************************************************************************/
- CagdBType CagdMakeCrvsCompatible(CagdCrvStruct **Crv1, CagdCrvStruct **Crv2,
- CagdBType SameOrder, CagdBType SameKV)
- {
- int KV1Len, KV2Len, RefLen;
- CagdRType *KV1, *KV2, *RefKV;
- CagdCrvStruct *TCrv;
- CagdPointType CommonPType;
-
- if ((*Crv1 == NULL) || (*Crv2 == NULL))
- return TRUE;
-
- CommonPType = CagdMergePointType((*Crv1) -> PType, (*Crv2) -> PType);
-
- /* Make the point types compatible. */
- if (CommonPType != (*Crv1) -> PType) {
- TCrv = CagdCoerceCrvTo(*Crv1, CommonPType);
- CagdCrvFree(*Crv1);
- *Crv1 = TCrv;
- }
- if (CommonPType != (*Crv2) -> PType) {
- TCrv = CagdCoerceCrvTo(*Crv2, CommonPType);
- CagdCrvFree(*Crv2);
- *Crv2 = TCrv;
- }
-
- if (SameOrder) {
- /* Raise the degree of the lower one. */
- if ((*Crv1) -> Order < (*Crv2) -> Order) {
- TCrv = CagdCrvDegreeRaiseN(*Crv1, (*Crv2) -> Order);
- CagdCrvFree(*Crv1);
- *Crv1 = TCrv;
- }
- else if ((*Crv2) -> Order < (*Crv1) -> Order) {
- TCrv = CagdCrvDegreeRaiseN(*Crv2, (*Crv1) -> Order);
- CagdCrvFree(*Crv2);
- *Crv2 = TCrv;
- }
- }
-
- /* If incompatible curve type - make it the same as well. */
- if ((*Crv1) -> GType != (*Crv2) -> GType) {
- /* If power basis - promote to bezier: */
- if ((*Crv1) -> GType == CAGD_CPOWER_TYPE) {
- TCrv = CnvrtPower2BezierCrv(*Crv1);
- CagdCrvFree(*Crv1);
- *Crv1 = TCrv;
- }
- if ((*Crv2) -> GType == CAGD_CPOWER_TYPE) {
- TCrv = CnvrtPower2BezierCrv(*Crv2);
- CagdCrvFree(*Crv2);
- *Crv2 = TCrv;
- }
-
- /* Now both curves may be either bezier or bspline curves. */
- if ((*Crv1) -> GType != (*Crv2) -> GType) {
- /* If bezier basis - promote to bspline: */
- if ((*Crv1) -> GType == CAGD_CBEZIER_TYPE) {
- TCrv = CnvrtBezier2BsplineCrv(*Crv1);
- CagdCrvFree(*Crv1);
- *Crv1 = TCrv;
- }
- if ((*Crv2) -> GType == CAGD_CBEZIER_TYPE) {
- TCrv = CnvrtBezier2BsplineCrv(*Crv2);
- CagdCrvFree(*Crv2);
- *Crv2 = TCrv;
- }
- }
- }
-
- if (SameKV) {
- /* If bspline curve - make sure knot vectors are the same. */
- if ((*Crv1) -> GType == CAGD_CBSPLINE_TYPE) {
- KV1 = (*Crv1) -> KnotVector;
- KV2 = (*Crv2) -> KnotVector;
- KV1Len = (*Crv1) -> Length + (*Crv1) -> Order;
- KV2Len = (*Crv2) -> Length + (*Crv2) -> Order;
-
- /* Affine map second knot vector to span same parametric domain. */
- BspKnotAffineTrans(KV2, KV2Len, KV1[0] - KV2[0],
- (KV1[KV1Len - 1] - KV1[0]) /
- (KV2[KV2Len - 1] - KV2[0]));
-
- /* Find knots in KV2 which are not in KV1 and refine Crv1 there. */
- RefKV = BspKnotSubtrTwo(KV2, KV2Len, KV1, KV1Len, &RefLen);
- if (RefLen > 0) {
- TCrv = CagdCrvRefineAtParams(*Crv1, FALSE, RefKV, RefLen);
- CagdCrvFree(*Crv1);
- *Crv1 = TCrv;
- KV1 = (*Crv1) -> KnotVector;
- KV1Len = (*Crv1) -> Length + (*Crv1) -> Order;
- }
- IritFree((VoidPtr) RefKV);
-
- /* Find knots in KV1 which are not in KV2 and refine Crv2 there. */
- RefKV = BspKnotSubtrTwo(KV1, KV1Len, KV2, KV2Len, &RefLen);
- if (RefLen > 0) {
- TCrv = CagdCrvRefineAtParams(*Crv2, FALSE, RefKV, RefLen);
- CagdCrvFree(*Crv2);
- *Crv2 = TCrv;
- }
- IritFree((VoidPtr) RefKV);
- }
- }
-
- return TRUE;
- }
-
- /******************************************************************************
- * Given two surfaces, make the compatible by: *
- * 1. Coercing their point type to be the same. *
- * 2. Make them have the same surface type. *
- * 3. Raising the degree of the lower one to be the same. *
- * 4. Refine them to common knot vectors (If Bspline). *
- * Note 3 is preformed if SameOrder TRUE, 4 if SameKV TRUE. *
- * Returns TRUE if succesfull. Both Surfaces are modified IN PLACE. *
- ******************************************************************************/
- CagdBType CagdMakeSrfsCompatible(CagdSrfStruct **Srf1, CagdSrfStruct **Srf2,
- CagdBType SameUOrder, CagdBType SameVOrder,
- CagdBType SameUKV, CagdBType SameVKV)
- {
- int i, KV1Len, KV2Len, RefLen;
- CagdRType *KV1, *KV2, *RefKV;
- CagdSrfStruct *TSrf;
- CagdPointType CommonPType;
-
- if ((*Srf1 == NULL) || (*Srf2 == NULL))
- return TRUE;
-
- CommonPType = CagdMergePointType((*Srf1) -> PType, (*Srf2) -> PType);
-
- /* Make the point types compatible. */
- if (CommonPType != (*Srf1) -> PType) {
- TSrf = CagdCoerceSrfTo(*Srf1, CommonPType);
- CagdSrfFree(*Srf1);
- *Srf1 = TSrf;
- }
- if (CommonPType != (*Srf2) -> PType) {
- TSrf = CagdCoerceSrfTo(*Srf2, CommonPType);
- CagdSrfFree(*Srf2);
- *Srf2 = TSrf;
- }
-
- if (SameUOrder) {
- /* Raise the degree of the lower one. */
- for (i = (*Srf1) -> UOrder; i < (*Srf2) -> UOrder; i++) {
- TSrf = CagdSrfDegreeRaise(*Srf1, CAGD_CONST_V_DIR);
- CagdSrfFree(*Srf1);
- *Srf1 = TSrf;
- }
- for (i = (*Srf2) -> UOrder; i < (*Srf1) -> UOrder; i++) {
- TSrf = CagdSrfDegreeRaise(*Srf2, CAGD_CONST_V_DIR);
- CagdSrfFree(*Srf2);
- *Srf2 = TSrf;
- }
- }
- if (SameVOrder) {
- for (i = (*Srf1) -> VOrder; i < (*Srf2) -> VOrder; i++) {
- TSrf = CagdSrfDegreeRaise(*Srf1, CAGD_CONST_U_DIR);
- CagdSrfFree(*Srf1);
- *Srf1 = TSrf;
- }
- for (i = (*Srf2) -> VOrder; i < (*Srf1) -> VOrder; i++) {
- TSrf = CagdSrfDegreeRaise(*Srf2, CAGD_CONST_U_DIR);
- CagdSrfFree(*Srf2);
- *Srf2 = TSrf;
- }
- }
-
- /* If incompatible surface type - make it the same as well. */
- if ((*Srf1) -> GType != (*Srf2) -> GType) {
- /* If power basis - promote to bezier: */
- if ((*Srf1) -> GType == CAGD_SPOWER_TYPE) {
- TSrf = CnvrtPower2BezierSrf(*Srf1);
- CagdSrfFree(*Srf1);
- *Srf1 = TSrf;
- }
- if ((*Srf2) -> GType == CAGD_SPOWER_TYPE) {
- TSrf = CnvrtPower2BezierSrf(*Srf2);
- CagdSrfFree(*Srf2);
- *Srf2 = TSrf;
- }
-
- /* Now both surfaces may be either bezier or bspline surfaces. */
- if ((*Srf1) -> GType != (*Srf2) -> GType) {
- /* If bezier basis - promote to bspline: */
- if ((*Srf1) -> GType == CAGD_SBEZIER_TYPE) {
- TSrf = CnvrtBezier2BsplineSrf(*Srf1);
- CagdSrfFree(*Srf1);
- *Srf1 = TSrf;
- }
- if ((*Srf2) -> GType == CAGD_SBEZIER_TYPE) {
- TSrf = CnvrtBezier2BsplineSrf(*Srf2);
- CagdSrfFree(*Srf2);
- *Srf2 = TSrf;
- }
- }
- }
-
- if ((*Srf1) -> GType == CAGD_SBSPLINE_TYPE) {
- /* If bspline surface - make sure knot vectors are the same. */
-
- if (SameUKV) {
- /* Handle the U Direction. */
- KV1 = (*Srf1) -> UKnotVector;
- KV2 = (*Srf2) -> UKnotVector;
- KV1Len = (*Srf1) -> ULength + (*Srf1) -> UOrder;
- KV2Len = (*Srf2) -> ULength + (*Srf2) -> UOrder;
-
- /* Affine map second knot vector to span same parametric domain. */
- BspKnotAffineTrans(KV2, KV2Len, KV1[0] - KV2[0],
- (KV1[KV1Len - 1] - KV1[0]) /
- (KV2[KV2Len - 1] - KV2[0]));
-
- /* Find knots in KV2 which are not in KV1 and refine Srf1 there. */
- RefKV = BspKnotSubtrTwo(KV2, KV2Len, KV1, KV1Len, &RefLen);
- if (RefLen > 0) {
- TSrf = CagdSrfRefineAtParams(*Srf1, CAGD_CONST_U_DIR,
- FALSE, RefKV, RefLen);
- CagdSrfFree(*Srf1);
- *Srf1 = TSrf;
- KV1 = (*Srf1) -> UKnotVector;
- KV1Len = (*Srf1) -> ULength + (*Srf1) -> UOrder;
- }
- IritFree((VoidPtr) RefKV);
-
- /* Find knots in KV1 which are not in KV2 and refine Srf2 there. */
- RefKV = BspKnotSubtrTwo(KV1, KV1Len, KV2, KV2Len, &RefLen);
- if (RefLen > 0) {
- TSrf = CagdSrfRefineAtParams(*Srf2, CAGD_CONST_U_DIR,
- FALSE, RefKV, RefLen);
- CagdSrfFree(*Srf2);
- *Srf2 = TSrf;
- }
- IritFree((VoidPtr) RefKV);
- }
-
- if (SameVKV) {
- /* Handle the V Direction. */
- KV1 = (*Srf1) -> VKnotVector;
- KV2 = (*Srf2) -> VKnotVector;
- KV1Len = (*Srf1) -> VLength + (*Srf1) -> VOrder;
- KV2Len = (*Srf2) -> VLength + (*Srf2) -> VOrder;
-
- /* Affine map second knot vector to span same parametric domain. */
- BspKnotAffineTrans(KV2, KV2Len, KV1[0] - KV2[0],
- (KV1[KV1Len - 1] - KV1[0]) /
- (KV2[KV2Len - 1] - KV2[0]));
-
- /* Find knots in KV2 which are not in KV1 and refine Srf1 there. */
- RefKV = BspKnotSubtrTwo(KV2, KV2Len, KV1, KV1Len, &RefLen);
- if (RefLen > 0) {
- TSrf = CagdSrfRefineAtParams(*Srf1, CAGD_CONST_V_DIR,
- FALSE, RefKV, RefLen);
- CagdSrfFree(*Srf1);
- *Srf1 = TSrf;
- KV1 = (*Srf1) -> VKnotVector;
- KV1Len = (*Srf1) -> VLength + (*Srf1) -> VOrder;
- }
- IritFree((VoidPtr) RefKV);
-
- /* Find knots in KV1 which are not in KV2 and refine Srf2 there. */
- RefKV = BspKnotSubtrTwo(KV1, KV1Len, KV2, KV2Len, &RefLen);
- if (RefLen > 0) {
- TSrf = CagdSrfRefineAtParams(*Srf2, CAGD_CONST_V_DIR,
- FALSE, RefKV, RefLen);
- CagdSrfFree(*Srf2);
- *Srf2 = TSrf;
- }
- IritFree((VoidPtr) RefKV);
- }
- }
-
- return TRUE;
- }
-
-